From 01397071d46ce6d3f736a4fc05d286d8030a7be4 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sun, 16 Aug 2015 10:47:39 -0700 Subject: [PATCH] Run cargo with a large stack There have been a number of reports of Cargo triggering a stack overflow in the algorithm implemented in `cargo::core::resolve`, and although many attempts have been made to reduce the stack space of the two relevant recursive functions it seems likely that this will not always be enough. For now, before moving the recursion to the heap manually, spawn the main thread with a large stack (e.g. mirror what the compiler does) to ensure that the same scenarios happen across platforms at least. Currently on my machine I get a 2MB stack on Linux and a 512K stack on OSX, so bumping this up to 8MB should be more than enough for the recursion in this algorithm. I also hope that with nonzeroing drop a few of the recursive calls will be able to become tail recursive, which should also help with stack space! Closes #1897 --- src/bin/cargo.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/bin/cargo.rs b/src/bin/cargo.rs index bfa763852..344235720 100644 --- a/src/bin/cargo.rs +++ b/src/bin/cargo.rs @@ -11,6 +11,7 @@ use std::fs; use std::io; use std::path::{PathBuf, Path}; use std::process::Command; +use std::thread::Builder; use cargo::{execute_main_without_stdin, handle_error, shell}; use cargo::core::MultiShell; @@ -57,7 +58,18 @@ See 'cargo help ' for more information on a specific command. fn main() { env_logger::init().unwrap(); - execute_main_without_stdin(execute, true, USAGE) + + // Right now the algorithm in cargo::core::resolve is pretty recursive and + // runs the risk of blowing the stack. Platforms tend to have different + // stack limits by default (I just witnessed 512K on OSX and 2MB on Linux) + // so to get a consistent experience just spawn ourselves with a large stack + // size. + let stack_size = env::var("CARGO_STACK_SIZE").ok() + .and_then(|s| s.parse().ok()) + .unwrap_or(8 * 1024 * 1024); // 8MB + Builder::new().stack_size(stack_size).spawn(|| { + execute_main_without_stdin(execute, true, USAGE) + }).unwrap().join().unwrap(); } macro_rules! each_subcommand{ ($mac:ident) => ({ -- 2.30.2